use std::fmt::Debug;

use reqwest::header::{HeaderMap, HeaderValue};
use serde::de::DeserializeOwned;

use crate::runtime::error::MagicBoxError;
use crate::runtime::response::Code;
use crate::runtime::result::MagicBoxResult;

/// HTTP请求
pub(crate) async fn http_get_bytes(url: &str, headers: Option<HeaderMap>) -> MagicBoxResult<Vec<u8>> {
    let mut builder = reqwest::Client::new().get(url);
    if headers.is_some() {
        builder = builder.headers(headers.unwrap());
    }
    
    let response = builder.send().await;
    if response.is_err() {
        let err = response.unwrap_err().to_string();
        log::error!("网络请求失败: {}", err.as_str());

        return Err(MagicBoxError::new(Code::NetworkError, format!("网络请求失败: {}", err.as_str()).as_str()));
    }

    let response = response.unwrap();
    if !response.status().is_success() {
        let status = response.status();
        log::error!("网络请求失败: {}", status.as_str());

        return Err(MagicBoxError::new(Code::NetworkError, format!("网络请求失败: {}", status.as_str()).as_str()));
    }

    let response = response.bytes().await;
    if response.is_err() {
        let err = response.unwrap_err().to_string();
        log::error!("网络请求失败: {}", err.as_str());

        return Err(MagicBoxError::new(Code::NetworkError, format!("网络请求失败: {}", err.as_str()).as_str()));
    }

    let content = response.unwrap();
    Ok(content.to_vec())
}

/// 获取字节数组
pub(crate) async fn github_get_bytes(url: &str) -> MagicBoxResult<Vec<u8>> {
    let response = reqwest::Client::new().get(url).header("User-Agent", HeaderValue::from_str("request").unwrap()).send().await;
    if response.is_err() {
        let err = response.unwrap_err().to_string();
        log::error!("网络错误，无法下载文件: {}", err.as_str());

        return Err(MagicBoxError::new(Code::NetworkError, format!("网络错误，无法下载文件: {}", err.as_str()).as_str()));
    }

    let response = response.unwrap();
    if !response.status().is_success() {
        let status = response.status();
        log::error!("网络错误，无法下载文件: {}", status.as_str());

        return Err(MagicBoxError::new(Code::NetworkError, format!("网络错误，无法下载文件: {}", status.as_str()).as_str()));
    }

    let response = response.bytes().await;
    if response.is_err() {
        let err = response.unwrap_err().to_string();
        log::error!("网络错误，无法下载文件: {}", err.as_str());

        return Err(MagicBoxError::new(Code::NetworkError, format!("网络错误，无法下载文件: {}", err.as_str()).as_str()));
    }

    let content = response.unwrap();
    Ok(content.to_vec())
}

/// 下载并转为结构
pub(crate) async fn github_get_data<T: Debug + DeserializeOwned>(url: &str) -> MagicBoxResult<T> {
    let response = reqwest::Client::new().get(url).header("User-Agent", HeaderValue::from_str("request").unwrap()).send().await;
    if response.is_err() {
        let err = response.unwrap_err().to_string();
        log::error!("网络错误，无法下载文件: {}", err.as_str());

        return Err(MagicBoxError::new(Code::NetworkError, format!("网络错误，无法下载文件: {}", err.as_str()).as_str()));
    }

    let response = response.unwrap();
    if !response.status().is_success() {
        let status = response.status();
        log::error!("网络错误，无法下载文件: {}", status.as_str());

        return Err(MagicBoxError::new(Code::NetworkError, format!("网络错误，无法下载文件: {}", status.as_str()).as_str()));
    }

    let response = response.json::<T>().await;
    if response.is_err() {
        let err = response.unwrap_err().to_string();
        log::error!("网络错误，无法下载文件: {}", err.as_str());

        return Err(MagicBoxError::new(Code::NetworkError, format!("网络错误，无法下载文件: {}", err.as_str()).as_str()));
    }

    Ok(response.unwrap())
}